package org.beiji.services.getawayservice.filter;

import cn.hutool.core.collection.CollectionUtil;
import org.beiji.frameworks.base.constant.UserConstant;
import org.beiji.services.getawayservice.config.Config;
import org.beiji.services.getawayservice.toolkit.JWTUtil;
import org.beiji.services.getawayservice.toolkit.UserInfoDTO;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;

import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Objects;


public class TokenValidateGatewayFilterFactory extends AbstractGatewayFilterFactory<Config> {
    public TokenValidateGatewayFilterFactory() {
        super(Config.class);
    }

    /**
     * 注销用户时需要传递TOKEN
     */
    public static final String DELETION_PATH  = "/api/user-service/deletion";

    @Override
    public GatewayFilter apply(Config config) {
        return ((exchange, chain) -> {
            ServerHttpRequest request = exchange.getRequest();
            String requestPath = request.getPath().toString();

            // 只拦截黑名单路径
            if (isPathInBlackPreList(requestPath, config.getBlackPathPre())) {
                String token = request.getHeaders().getFirst("Authorization");
                UserInfoDTO userInfoDTO = JWTUtil.parseJwtToken(token);
                // 校验token
                if(!validateToken(userInfoDTO)){
                    ServerHttpResponse response = exchange.getResponse();
                    response.setStatusCode(HttpStatus.UNAUTHORIZED);
                    return response.setComplete();
                }

                // 自定义请求头
                ServerHttpRequest.Builder builder = exchange.getRequest().mutate().headers(httpHeaders -> {
                    httpHeaders.set(UserConstant.USER_ID_KEY, userInfoDTO.getUserId());
                    httpHeaders.set(UserConstant.USER_NAME_KEY, userInfoDTO.getUsername());
                    // todo
                    httpHeaders.set(UserConstant.REAL_NAME_KEY, URLEncoder.encode(userInfoDTO.getRealName(), StandardCharsets.UTF_8));

                    // 如果是注销用户，需要保留token
                    if (Objects.equals(requestPath, DELETION_PATH)) {
                        httpHeaders.set(UserConstant.USER_TOKEN_KEY, token);
                    }
                });

                return chain.filter(exchange.mutate().request(builder.build()).build());
            }

            return chain.filter(exchange);
        });
    }

    private boolean isPathInBlackPreList(String requestPath, List<String> blackPreList){
        if (CollectionUtil.isEmpty(blackPreList)) {
            return false;
        }

        return blackPreList.stream().anyMatch(requestPath::startsWith);
    }

    private boolean validateToken(UserInfoDTO userInfoDTO){
        return userInfoDTO!=null;
    }


}
